/****************************************************
          File Name:toDaemon.c
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Thu 09 Oct 2014 07:55:32 PM CST
*****************************************************/

#define _POSIX_SOURCE
#include"toDaemon.h" 

int toDaemon(void)
{
	int i, fd0,fd1,fd2;
	pid_t pid;
	struct rlimit rl;
	struct sigaction act;
	
	umask(0); 				/* reset mask */
	
	if(getrlimit(RLIMIT_NOFILE,&rl)<0) 		/* get maximum file descriptor */
		return -1;
	if((pid=fork())<0)
		return -1;
	else if(pid!=0) 			/* make an orphan */
		exit(0);
	
	/* make process be a senssion's leader
	 * ensure future opens won't alloacte controlling TTYs
	 */
	setsid(); 
	
	act.sa_handler=SIG_IGN; 	/* default ignore captured signal */
	sigemptyset(&act.sa_mask);
	act.sa_flags=0;
	if(sigaction(SIGHUP,&act,NULL)<0) 	/* ignore SIGHUP receive from kernel */
		return -1;
	
	if((pid=fork())<0) 	/* do fork again */
		return -1;
	else if(pid!=0) 	/* avoid process be a process group leader */
		exit(0);
	
	if(chdir("/")<0) 	/* optional, change directory to '/'; in this process 
		is not necessary */
		return -1;
	
	/* close all open file descriptors */
	if (rl.rlim_max == RLIM_INFINITY)
		rl.rlim_max = 1024;
	for (i = 0; i < rl.rlim_max; i++)
		close(i);
	
	/* attach file descriptors 0, 1, and 2 to /dev/null */
	fd0 = open("/dev/null", O_RDWR);
	fd1 = dup(0);
	fd2 = dup(0);
	
	/* initailize the log file */
	openlog(NULL, LOG_CONS, LOG_DAEMON);  /* use program file name */
	if(fd0!=0 || fd1!=1 || fd2!=2)
	{
		syslog(LOG_ERR,"unexpected file descriptors %d %d %d",fd0,fd1,fd2);
		return -1;
	}
	return 0;
}